package com.xl.qa.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.xl.basic.annotation.RoleIgnored;
import com.xl.basic.annotation.RoleValidated;
import com.xl.basic.entity.Result;
import com.xl.basic.entity.ResultEnums;
import com.xl.basic.entity.SPage;
import com.xl.basic.entity.UserInfo;
import com.xl.basic.utils.LoginUtils;
import com.xl.basic.utils.ServletUtils;
import com.xl.dao.domain.XlQuestionAnswer;
import com.xl.dao.domain.XlQuestionForm;
import com.xl.dao.domain.XlQuestionOrder;
import com.xl.qa.enmus.QuestionOrderStateEnums;
import com.xl.qa.entity.param.AddQuesOrderParam;
import com.xl.qa.entity.param.QueryQuesOrderParam;
import com.xl.qa.entity.param.UpdQuesAnswerParam;
import com.xl.qa.entity.param.UpdQuesOrderStateParam;
import com.xl.qa.entity.result.QuesOrderDetailsResult;
import com.xl.qa.service.QuestionOrderService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotBlank;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 钟勇
 * Create in 2024/1/17 10:28
 */
@Tag(name = "问卷订单管理")
@RestController
@RequestMapping("/api/QuestionOrder")
@RequiredArgsConstructor
@RoleValidated
public class QuestionOrderController {

    private final QuestionOrderService questionOrderService;

    @Operation(summary = "新增问卷订单")
    @PostMapping(value = "/addQuesOrder")
    @RoleIgnored
    public Result<String> addQuesOrder(@Validated AddQuesOrderParam param) {
        Result<UserInfo> userInfoRes = LoginUtils.getUserInfo();

        UserInfo userInfo = userInfoRes.getResult();
        if (StrUtil.isBlank(param.getUserId())) {
            if (userInfo == null || StrUtil.isBlank(userInfo.getUserId())) {
                return ResultEnums.BusinessError.getResult("用户信息为空");
            }

            param.setUserId(userInfo.getUserId());
        }

        return questionOrderService.addQuesOrder(param, userInfo);
    }

    @Operation(summary = "编辑问卷回答")
    @PostMapping(value = "/updQuesAnswer")
    @RoleIgnored
    public Result<Object> updQuesAnswer(@Validated UpdQuesAnswerParam param) {
        Result<UserInfo> userInfoRes = LoginUtils.getUserInfo();
        return questionOrderService.updQuesAnswer(param, userInfoRes.getResult());
    }

    @Operation(summary = "取消订单")
    @PostMapping(value = "/cancelQuesOrder")
    public Result<Object> cancelQuesOrder(
            @NotBlank(message = "订单ID不能为空") String orderId
            , @NotBlank(message = "取消原因不能为空") String remark
    ) {
        Result<UserInfo> userInfoRes = LoginUtils.getUserInfo();
        return questionOrderService.updQuesOrderState(new UpdQuesOrderStateParam()
                        .setOrderId(orderId)
                        .setOrderState(QuestionOrderStateEnums.cancel.getState())
                        .setRemark(remark)
                , userInfoRes.getResult());
    }

    @Operation(summary = "完成订单")
    @PostMapping(value = "/finishQuesOrder")
    public Result<Object> finishQuesOrder(
            @NotBlank(message = "订单ID不能为空") String orderId
    ) {
        Result<UserInfo> userInfoRes = LoginUtils.getUserInfo();
        return questionOrderService.updQuesOrderState(new UpdQuesOrderStateParam()
                        .setOrderId(orderId)
                        .setOrderState(QuestionOrderStateEnums.finish.getState())
                , userInfoRes.getResult());
    }

    @Operation(summary = "获取问卷订单明细")
    @PostMapping(value = "/getQuesOrderDetails")
    @RoleIgnored
    public Result<QuesOrderDetailsResult> getQuesOrderDetails(@NotBlank(message = "订单ID不能为空") String orderId) {
        return questionOrderService.getQuesOrderDetails(orderId);
    }

    @Operation(summary = "查询问卷订单列表")
    @PostMapping(value = "/queryQuesOrderList")
    public Result<List<QuesOrderDetailsResult>> queryQuesOrderList(@Validated QueryQuesOrderParam param) {
        return questionOrderService.queryQuesOrderList(param);
    }

    @Operation(summary = "查询问卷订单分页")
    @PostMapping(value = "/queryQuesOrderPage")
    public Result<List<QuesOrderDetailsResult>> queryQuesOrderPage(@Validated QueryQuesOrderParam param, SPage sPage) {
        return questionOrderService.queryQuesOrderPage(param, sPage);
    }

    @Operation(summary = "查询我的问卷订单分页")
    @PostMapping(value = "/queryMyQuesOrderPage")
    @RoleIgnored
    public Result<List<QuesOrderDetailsResult>> queryMyQuesOrderPage(@Validated QueryQuesOrderParam param, SPage sPage) {
        Result<UserInfo> userInfoRes = LoginUtils.getUserInfo();

        UserInfo userInfo = userInfoRes.getResult();
        if (userInfo == null || StrUtil.isBlank(userInfo.getUserId())) {
            return ResultEnums.BusinessError.getResult("用户信息为空");
        }
        param.setUserId(userInfo.getUserId());

        return questionOrderService.queryQuesOrderPage(param, sPage);
    }

    @Operation(summary = "导出问卷订单")
    @GetMapping(value = "/exportQuesOrderExcel")
    public void exportQuesOrderExcel(@Validated QueryQuesOrderParam param) {
        param.setAnswerDetailFlag(1).setQuestionDetailFlag(1);
        Result<List<QuesOrderDetailsResult>> listRes = questionOrderService.queryQuesOrderList(param);
        List<QuesOrderDetailsResult> list = listRes.getResult() != null ? listRes.getResult() : new ArrayList<>();

        //excel中是否导出回答，及回答的模板
        List<XlQuestionForm> quesForm = new ArrayList<>();
        if (list.stream().map(QuesOrderDetailsResult::getQuestionId).distinct().count() == 1) {
            quesForm = list.get(0).getQuestion().getForm();
        }

        BigDecimal yuan = BigDecimal.valueOf(100);

        List<XlQuestionForm> finalQuesForm = quesForm;

        List<Map<String, Object>> rowList = list.stream().map(item -> {
            String price = item.getPrice() == null ? "0.00" : NumberUtil.roundStr(
                    String.valueOf(NumberUtil.div(item.getPrice(), yuan)), 2
            );

            Map<String, Object> row = new LinkedHashMap<>();
            row.put("订单号", item.getOrderId());
            row.put("培训课程", item.getQuestionTitle());
            row.put("金额(元)", price);
            row.put("提交时间", item.getAddTime() == null ? null : LocalDateTimeUtil.format(item.getAddTime(), "yyyy-MM-dd HH:mm:ss"));
            row.put("支付时间", item.getPayTime() == null ? null : LocalDateTimeUtil.format(item.getPayTime(), "yyyy-MM-dd HH:mm:ss"));
            row.put("订单状态", QuestionOrderStateEnums.getByState(item.getState()).getDesc());
            row.put("取消备注", item.getCancelRemark());
            row.put("取消时间", item.getCancelTime() == null ? null : LocalDateTimeUtil.format(item.getCancelTime(), "yyyy-MM-dd HH:mm:ss"));

            List<XlQuestionAnswer> answerList = item.getAnswer();
            finalQuesForm.forEach(formRow -> {
                XlQuestionAnswer answer = answerList.stream().filter(
                        currAnswer -> currAnswer.getRowId().equals(formRow.getRowId())
                ).findAny().orElse(null);
                row.put(formRow.getRowTitle(), answer == null ? null : answer.getRowValue());
            });

            return row;
        }).toList();


        ExcelWriter writer = ExcelUtil.getWriter();
        writer.write(rowList, true);

        HttpServletResponse response = ServletUtils.getResponse();
        response.setContentType("application/vnd.ms-excel;charset=utf-8");

        String excelName = "questionOrder-" + LocalDateTimeUtil.format(LocalDateTime.now(), "yyyyMMdd");
        response.setHeader("Content-Disposition", "attachment;filename=" + excelName + ".xls");
        try (ServletOutputStream out = response.getOutputStream()) {
            writer.flush(out, true);
        } catch (IOException ignored) {
        }
    }
}
